<template>
  <div class="row padding-page q-ma-md">
    <q-card flat bordered class="col-12">
      <!-- 上面的卡片标题 -->
      <q-card-section class="row col-12">
        <div class="q-pr-lg">
          <div class="text-subtitle1 text-bold text-primary">
            Survival-associated MNVQTLs across different cancer types
          </div>
          <div class="text-body2">
            We totally identified {{ dataStat.survival.either }} unique MNVQTLs
            associated (Log rank test P-value &lt; 0.05) with patient overall
            survival ({{ dataStat.survival.additive }} in the additive model,
            {{ dataStat.survival.recessive }} in the recessive model, and
            {{ dataStat.survival.dominant }} in the dominant model) across
            different cancer types for users to search or browse.
          </div>
        </div>
        <q-space />
        <div>
          <q-btn
            class="absolute-right"
            color="primary"
            flat
            dense
            :icon="formExpand ? 'keyboard_arrow_up' : 'keyboard_arrow_down'"
            :ripple="false"
            @click="formExpand = !formExpand"
          />
        </div>
      </q-card-section>
      <q-separator />
      <!-- 表单内容 -->
      <q-form v-show="formExpand" @submit="onSubmit" @reset="onReset">
        <!-- 表单主体 -->
        <q-card-section
          class="row col-12 justify-center q-gutter-x-lg q-gutter-y-sm q-pb-none"
        >
          <!-- 癌症类型 -->
          <q-select
            class="col-12 col-sm-2"
            :dense="smallScreen"
            v-model="queryCancer"
            use-input
            input-debounce="0"
            label="Cancer Type"
            :options="filteredCancerList"
            @filter="onCancerFilter"
          >
            <template v-slot:no-option>
              <q-item>
                <q-item-section class="text-grey"> No results </q-item-section>
              </q-item>
            </template>
          </q-select>
          <q-select
            class="col-12 col-sm-2"
            :dense="smallScreen"
            label="Model"
            v-model="queryModel"
            :options="['additive', 'dominant', 'recessive']"
          >
          </q-select>
          <!-- MNV查询 -->
          <q-input
            class="col-12 col-sm-4"
            clearable
            :dense="smallScreen"
            hide-bottom-space
            lazy-rules="ondemand"
            ref="inputVariantRef"
            v-model="queryVariant"
            label="MNV ID or rsID"
            :rules="queryRules"
          />
        </q-card-section>
        <!-- 表单按钮 -->
        <q-card-section
          class="row col-12 justify-center items-center q-gutter-x-xl q-gutter-y-sm"
        >
          <q-btn
            no-caps
            unelevated
            icon="search"
            color="primary"
            label="Search"
            size="md"
            type="submit"
          />
          <q-btn
            no-caps
            unelevated
            icon="refresh"
            color="negative"
            label="Reset"
            size="md"
            type="reset"
          />
        </q-card-section>
        <!-- 查询提示 -->
        <q-card-section
          class="row col-12 justify-center q-gutter-x-md q-gutter-y-xs"
        >
          <span class="col-auto self-center">Search examples:</span>
          <q-btn
            class="row col-auto text-body2"
            no-caps
            flat
            :ripple="false"
            v-for="example in searchExamples"
            :key="example.query"
            :label="example.model === 'dominal' ? 'dominant' : example.model"
            @click="queryExample(example)"
            color="secondary"
            text-color="primary"
          />
        </q-card-section>
      </q-form>
    </q-card>
  </div>
  <div class="row padding-page q-ma-md">
    <q-card flat bordered class="col-12 q-pa-md">
      <q-card-section class="no-padding">
        <q-table
          flat
          row-key="label"
          v-model:pagination="tablePagination"
          :rows="tableRows"
          :columns="tableColumns"
          :dense="smallScreen"
          :rows-per-page-label="t('resultPage.rows_per_page_label')"
          :loading="tableLoading"
          :rows-per-page-options="[10, 20, 50]"
          :pagination-label="
            (firstRowIndex, endRowIndex, totalRowsNumber) =>
              `${firstRowIndex}~${endRowIndex} / ${totalRowsNumber}`
          "
          @request="onRequest"
        >
          <template v-slot:top="props">
            <div class="row col-12">
              <q-space />
              <div class="row q-gutter-x-sm">
                <q-btn
                  flat
                  :ripple="false"
                  dense
                  :icon="props.inFullscreen ? 'fullscreen_exit' : 'fullscreen'"
                  @click="props.toggleFullscreen"
                />
                <q-btn
                  icon="file_download"
                  no-caps
                  flat
                  :ripple="false"
                  dense
                  @click="exportTable"
                />
              </div>
            </div>
          </template>
          <template v-slot:header="props">
            <q-tr :props="props">
              <q-th
                v-for="col in props.cols"
                :key="col.name"
                :props="props"
                style="
                  font-weight: bold;
                  font-size: 14px;
                  color: var(--q-primary);
                "
              >
                {{ col.label }}
              </q-th>
            </q-tr>
          </template>
          <template v-slot:body-cell-plot="props">
            <q-td key="plot" :props="props">
              <q-btn
                size="md"
                color="primary"
                icon="ssid_chart"
                dense
                rounded
                outline
                @click="showKMplot(props.row)"
              >
                <q-tooltip> Show KMplot </q-tooltip>
              </q-btn>
            </q-td>
          </template>
        </q-table>
      </q-card-section>
    </q-card>
  </div>
  <q-dialog v-model="modalShow">
    <q-card style="width: 560px; height: 600px">
      <q-card-section class="fit"
        ><iframe :src="pdfPath" class="fit"
      /></q-card-section>
    </q-card>
  </q-dialog>
</template>

<script setup lang="ts">
import { exportFile, useQuasar } from 'quasar';
import { ref, computed, onMounted, reactive } from 'vue';
import { useI18n } from 'vue-i18n';

import { cancerType } from 'src/interface/cancerType';
import { survivalResultColumns } from 'src/model/survivalResult';
import { querySurvival } from 'src/apis/querySurvival';
import { queryKMPlot } from 'src/apis/queryKMPlot';

import { getDataCounts } from 'src/boot/dataCount';

const { t } = useI18n({ useScope: 'global' });
const $q = useQuasar();
const smallScreen = computed((): boolean => {
  return !$q.screen.gt.sm;
});

// 查询示例
const searchExamples = [
  {
    query: 'rs780672,rs780673',
    cancer_type: 'BRCA',
    model: 'dominant',
  },
  {
    query: 'rs1965943,rs2171180',
    cancer_type: 'GBM',
    model: 'additive',
  },
  {
    query: 'rs35671023,rs35857744',
    cancer_type: 'KIRP',
    model: 'recessive',
  },
];
const queryExample = (params) => {
  queryVariant.value = params.query;
  queryModel.value = params.model;
  queryCancer.value = params.cancer_type;
};

// 表单状态以及固定值
const formExpand = ref(true);
const cancerTypeList = [
  'ALL',
  'ACC',
  'BLCA',
  'BRCA',
  'CESC',
  'CHOL',
  'COAD',
  'DLBC',
  'ESCA',
  'GBM',
  'HNSC',
  'KICH',
  'KIRC',
  'KIRP',
  'LGG',
  'LIHC',
  'LUAD',
  'LUSC',
  'MESO',
  'OV',
  'PAAD',
  'PCPG',
  'PRAD',
  'READ',
  'SARC',
  'SKCM',
  'STAD',
  'TGCT',
  'THCA',
  'THYM',
  'UCEC',
  'UCS',
  'UVM',
];
const filteredCancerList = ref(cancerTypeList);

const dataStat = getDataCounts();

// 表单查询参数
const queryCancer = ref<cancerType>('ALL');
const queryVariant = ref('');
const inputVariantRef = ref(null);
const queryModel = ref('additive');

// 表单方法
//TODO 验证规则
const queryRules = [
  (val) => {
    const containSpecial = (s: string) => {
      var containSpecial = RegExp(
        /[(\ )(\~)(\!)(\@)(\#)(\$)(\%)(\^)(\&)(\*)(\()(\))(\+)(\=)(\[)(\])(\{)(\})(\|)(\\)(\;)(\')(\")(\.)(\/)(\<)(\>)(\?)(\)]+/
      );
      return containSpecial.test(s);
    };

    if (!containSpecial(val)) {
      return true;
    } else {
      return t('queryForm.allertMessages.hasSpecial');
    }
  },
];
const onCancerFilter = (val, update) => {
  if (val === '') {
    update(() => {
      filteredCancerList.value = cancerTypeList;
    });
    return;
  }
  update(() => {
    const needle = val.toLowerCase();
    filteredCancerList.value = cancerTypeList.filter(
      (v) => v.toLowerCase().indexOf(needle) > -1
    );
  });
};
const onSubmit = () => {
  inputVariantRef.value.validate();
  if (!inputVariantRef.value.hasError) {
    currentShow.cancer = queryCancer.value;
    currentShow.query = queryVariant.value;
    currentShow.model = queryModel.value;
    tablePagination.value.page = 1;
    fetchData(currentShow.query, currentShow.cancer, currentShow.model);
  }
};
const onReset = () => {
  queryCancer.value = 'ALL';
  queryVariant.value = '';
  queryModel.value = '';
};

// 查询数据
const fetchData = (
  MNV_id: string | null,
  cancer_type: cancerType = 'ALL',
  model: 'additive' | 'dominant' | 'recessive' = 'additive',
  page = 1,
  size = 10,
  sortBy = 'log_rank_p',
  descending: 0 | 1 = 0
) => {
  tableColumns.value = survivalResultColumns;
  querySurvival({
    MNV_id: MNV_id ? MNV_id : null,
    cancer_type: cancer_type ? cancer_type : 'ALL',
    model: model,
    page: page,
    size: size,
    sortBy: sortBy,
    descending: descending,
  })
    .then((response) => {
      tableRows.value = response.data.data_source;
      tablePagination.value.rowsNumber = response.data.total;
    })
    .catch((error) => {
      $q.dialog({
        title: 'Error',
        html: true,
        message: `Something wrong happened when searching: <br/>${error}`,
      })
        .onOk(() => {
          //
        })
        .onCancel(() => {
          // console.log('Cancel')
        })
        .onDismiss(() => {
          // console.log('I am triggered on both OK and Cancel')
        });
    });
};

// 表格的数据
const tableColumns = ref(survivalResultColumns);
const tableRows = ref([]);
const tableLoading = ref(false);
const tablePagination = ref({
  sortBy: 'log_rank_p',
  descending: false,
  page: 1,
  rowsPerPage: 10,
  rowsNumber: 0,
});
const currentShow = reactive({
  cancer: <cancerType>'ALL',
  query: <string>'',
  model: <'additive' | 'dominant' | 'recessive'>'additive',
});

// 表格方法
const onRequest = (props) => {
  tableLoading.value = true;
  // 从表格获取当前的分页信息和排序信息
  const { page, rowsPerPage, sortBy, descending } = props.pagination;
  fetchData(
    currentShow.query,
    currentShow.cancer,
    currentShow.model,
    page,
    rowsPerPage,
    sortBy,
    descending ? 1 : 0
  );
  // don't forget to update local pagination object
  tablePagination.value.page = page;
  tablePagination.value.rowsPerPage = rowsPerPage;
  tablePagination.value.sortBy = sortBy;
  tablePagination.value.descending = descending;
  tableLoading.value = false;
};

const wrapCsvValue = (val, formatFn, row) => {
  let formatted = formatFn !== void 0 ? formatFn(val, row) : val;
  formatted =
    formatted === void 0 || formatted === null ? '' : String(formatted);
  formatted = formatted.split('"').join('""');
  return `${formatted}`;
};
const exportTable = () => {
  querySurvival({
    cancer_type: currentShow.cancer,
    page: 1,
    size: tablePagination.value.rowsNumber,
  }).then((response) => {
    const content = [
      survivalResultColumns
        .map((col) => wrapCsvValue(col.label))
        .slice(1)
        .join('\t'),
    ]
      .concat(
        response.data.data_source.map((row) =>
          tableColumns.value
            .map((col) =>
              wrapCsvValue(
                typeof col.field === 'function'
                  ? col.field(row)
                  : row[col.field === void 0 ? col.name : col.field],
                col.format,
                row
              )
            )
            .slice(1)
            .join('\t')
        )
      )
      .join('\r\n');
    const status = exportFile(
      `${queryCancer.value === null ? 'ALL' : queryCancer.value}_survival_MNVs`,
      content,
      'text'
    );

    if (status !== true) {
      $q.notify({
        message: 'Something wrong happened while download...',
        color: 'negative',
        icon: 'warning',
      });
    }
  });
};

// 初始化行为
onMounted(() => {
  tableLoading.value = true;
  querySurvival({
    cancer_type: 'ALL',
    MNV_id: null,
    page: 1,
    size: 10,
  })
    .then((response) => {
      if (response.data.total > 0) {
        tablePagination.value.rowsNumber = response.data.total;
        tableColumns.value = survivalResultColumns;
        tableRows.value = response.data.data_source;
        tableLoading.value = false;
      } else {
        tableLoading.value = false;
        $q.dialog({
          title: 'Warning',
          message: 'No results found, please try another',
        })
          .onOk(() => {
            // console.log('')
          })
          .onCancel(() => {
            // console.log('Cancel')
          })
          .onDismiss(() => {
            // console.log('I am triggered on both OK and Cancel')
          });
      }
    })
    .catch((error) => {
      tableLoading.value = false;
      $q.dialog({
        title: 'Error',
        html: true,
        message: `Something wrong happened when searching: <br/>${error}`,
      })
        .onOk(() => {
          //
        })
        .onCancel(() => {
          // console.log('Cancel')
        })
        .onDismiss(() => {
          // console.log('I am triggered on both OK and Cancel')
        });
    });
});

const modalShow = ref(false);
const pdfPath = ref('');
const showKMplot = (params) => {
  modalShow.value = true;
  queryKMPlot({
    MNV_id: params.MNV_id,
    cancer_type: params.cancer_type,
    model: params.model,
  }).then((response) => {
    // const blob = new Blob([response.data], { type: response.data.type });
    // const url = window.URL.createObjectURL(blob);
    pdfPath.value = response.data;
  });
};
</script>

<style scoped lang="scss"></style>
